import sys
import os
from pathlib import Path
from PySide6.QtWidgets import QApplication
from PySide6.QtCore import QModelIndex, QSettings,QObject,Slot,QMutex,Signal,Property,QAbstractListModel
from PySide6.QtGui import QIcon
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle
# import rc_gallery
import platform
# import myglobal
import logging
import config_json
import Bridge
from logging.handlers import RotatingFileHandler
import getpath
sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf8', buffering=1)
sys.stderr = open(sys.stderr.fileno(), mode='w', encoding='utf8', buffering=1)
handlers = [RotatingFileHandler(filename="report.log", maxBytes=10 * 1024 * 1024, encoding='utf-8', backupCount=3),
            logging.StreamHandler(sys.stdout)]
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s -%(funcName)s - %(message)s',
                    handlers=handlers)
logging.info('begin')
class TaskItem(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.m_title = ''
        self.m_done =False
        self.m_color=None
        self.m_order=None
    titleChanged=Signal()
    @Property(str,notify=titleChanged)
    def title(self):
        return self.m_title

    @title.setter
    def title(self, name):
        self.m_title = name
    doneChanged=Signal()
    @Property(bool,notify=doneChanged)
    def done(self):
        return self.m_done

    @done.setter
    def done(self, name):
        self.m_done = name
    colorChanged=Signal()
    @Property(str,notify=colorChanged)
    def color(self):
        return self.m_color

    @title.setter
    def color(self, name):
        self.m_title = name

    orderChanged=Signal()
    @Property(str,notify=orderChanged)
    def order(self):
        return self.m_order

    @title.setter
    def order(self, name):
        self.m_order = name
class TaskModel(QAbstractListModel):
    sizeChanged=Signal(int)
    def __init__(self,parent=None):
        super().__init__(parent)
        self.m_taskList=[]
    def rowCount(self,parent):
        return len(self.m_taskList)
    def data(self,index, role):
        if (not index.isValid()):
            return None

        if index.row() >= 0 or index.row() < m_taskList.count():
            if role == TaskTextRole:
                return self.m_taskList[index.row()].title
            elif (role == TaskIsDoneRole):
                return self.m_taskList[index.row()].done
            elif (role == TaskIndexRole):
                return index.row();
            elif (role == ObjectRole):
                return self.m_taskList[index.row()]
        return None
    def roleNames(self):
        names = {}
        names[hash(TaskTextRole)] = "taskText".encode()
        names[hash(TaskIsDoneRole)] = "isDone".encode()
        names[hash(TaskIndexRole)] = "taskIndex".encode()
        names[hash(ObjectRole)] = "object".encode()
        return names
    def addTask(self,task):
        i=task.order
        if i<0:
            return
        while(i<len(self.m_taskList)):
            self.m_taskList[i].order=i+1
            i+=1

        self.beginInsertRows(QModelIndex(), task.order, task.order);
        self.m_taskList.insert(task.order, task);
        self.endInsertRows();

        self.sizeChanged.emit(self.size());
    def size(self):
        return len(self.m_taskList)
    def takeTask(self,task):
        if (self.m_taskList.contains(task)):
            i=task.order()+1
            while(i <self.size()):
                self.m_taskList[i].Order=i-1
                i+=1

            self.beginRemoveRows(QModelIndex(), self.m_taskList.indexOf(task), self.m_taskList.indexOf(task));
            self.m_taskList.removeOne(task);
            self.endRemoveRows();

            self.sizeChanged(self.size());
            return True;
        else:
            return False;
class Backend(QObject):
    @Slot()
    def appVersion(self):
        return "1.0"
    def __init__(self):
        super().__init__()
        self.m_taskList=[]
        self.m_doneTaskModel=TaskModel()
        self.m_newTaskModel=TaskModel()
        self.loadTasks()
    def newTaskModel(self):
        return self.m_newTaskModel;
    def doneTaskModel(self):
        return self.m_doneTaskModel;
    @Slot(str,int)
    def newTask(self,text, color):
        task = TaskItem()
        task.title=text
        task.done=False
        task.color=color#, 0)
        task.order=0
        task.doneChanged.connect(self.taskStateChanged)
        task.titleChanged.connect(self.scheduleSaveTasks)
        task.orderChanged.connect(self.scheduleSaveTasks)
        self.m_taskList.insert(0,task)
        self.m_newTaskModel.addTask(task);
        self.scheduleSaveTasks();

    def deleteCompletedTask(self,task):
        if (not task):
            return;
        if (m_doneTaskModel.takeTask(task)):
            m_taskList.removeOne(task);
            self.scheduleSaveTasks();


    def loadTasks(self):
        size =len(config_json.setting["todos"])
        for i in range(size):
            one=config_json.setting["todos"][i]
            task = TaskItem(one["taskText"],one["isDone"],one["color"],one["order"])
            task.doneChanged.connect(self.taskStateChanged)
            task.titleChanged.connect(self.scheduleSaveTasks)
            task.orderChanged.connect(self.scheduleSaveTasks)
            self.m_taskList.append(task);

        # qSort(m_taskList.begin(), m_taskList.end(),
        #       [](model::TaskItem* a, model::TaskItem* b) . bool { return a.order() < b.order(); });

        for task in self.m_taskList:
            if (task.done):
                self.m_doneTaskModel.addTask(task);
            else:
                self.m_newTaskModel.addTask(task);
        # qDebug() << "Loaded tasks: " << m_taskList.size();

    def scheduleSaveTasks(self):
        # QtConcurrent::run(self, self.saveTasks);
        pass

    def saveTasks(self):
        pass
        # QMutexLocker locker(&gTaskListMutex);

        # QSettings settings("IProApps", "BestToDoList");
        # settings.beginWriteArray("todos");
        # for (int i = 0; i < m_taskList.size(); ++i) {
        #     settings.setArrayIndex(i);
        #     settings.setValue("taskText", m_taskList.at(i).title());
        #     settings.setValue("isDone", m_taskList.at(i).done());
        #     settings.setValue("color", m_taskList.at(i).color());
        #     settings.setValue("order", m_taskList.at(i).order());
        # }
        # settings.endArray();

        # qDebug() << "Saved tasks: " << m_taskList.size();

    def taskStateChanged(self):
        task=self.sender()
        if task is TaskItem:
            if (task.done()):
                self.m_newTaskModel.takeTask(task);
                task.setOrder(self.m_doneTaskModel.size());
                self.m_doneTaskModel.addTask(task);
            else:
                self.m_doneTaskModel.takeTask(task);
                task.setOrder(self.m_newTaskModel.size());
                self.m_newTaskModel.addTask(task);
            self.scheduleSaveTasks();

def main():
    # if platform.uname().system=="Windows":
    #     pass
    # else:
    #     from Watcher import Watcher
    #     Watcher()
    QApplication.setApplicationName("report")
    # QApplication.setOrganizationName("QtProject")

    app = QApplication(sys.argv)
    # myglobal.app = app
    # print(dir(app))
    QIcon.setThemeName("gallery")
    config_json.read_setting()
    settings = QSettings()
    if not os.environ.get("QT_QUICK_CONTROLS_STYLE"):
        style_name = settings.value("style")
        if style_name:
            QQuickStyle.setStyle(style_name)
    QQuickStyle.setStyle("Fusion")
    engine = QQmlApplicationEngine()
    backend=Backend()
    engine.rootContext().setContextProperty("backend", backend);
    # myglobal.engine = engine
    # built_in_styles = ["Basic", "Fusion", "Imagine", "Material", "Universal"]
    # if platform.system() == "Darwin":
    #     built_in_styles.append("macOS")
    # elif platform.system() == "Windows":
    #     built_in_styles.append("Windows")
    # engine.setInitialProperties({"builtInStyles": built_in_styles})

    # Get the path of the current directory, and then add the name
    # of the QML file, to load it.
    qml_file =os.path.join(getpath.getpath(),"main.qml")  # 'mainw.qml'
    engine.load(qml_file)

    if not engine.rootObjects():
        sys.exit(-1)
    r = app.exec()
    config_json.write_setting()
    sys.exit(r)


if __name__ == '__main__':
    main()
